package com.songlanyun.modules.chain.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.enums.BillConstant;
import com.songlanyun.common.enums.BillConstant.BillMode;
import com.songlanyun.common.enums.ChainConstant;
import com.songlanyun.common.enums.ChainConstant.ChainBsStatus;
import com.songlanyun.common.enums.ChainConstant.ChainBsType;
import com.songlanyun.common.enums.ChainConstant.ChainPayType;
import com.songlanyun.common.enums.ChainConstant.ChainTransferNet;
import com.songlanyun.common.enums.IntegralConstant.InnerMode;
import com.songlanyun.common.enums.IntegralConstant.IntegralModelType;
import com.songlanyun.common.enums.IntegralConstant.OuterMode;
import com.songlanyun.common.exception.BizCodeEnum;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.*;
import com.songlanyun.common.utils.custom.MathUtils;
import com.songlanyun.config.ChainProperties;
import com.songlanyun.modules.account.dao.HandlingFeesDao;
import com.songlanyun.modules.account.entity.AccountEntity;
import com.songlanyun.modules.account.entity.HandlingFeesEntity;
import com.songlanyun.modules.account.entity.UserIdentityAssetEntity;
import com.songlanyun.modules.account.service.AccountService;
import com.songlanyun.modules.account.service.CommonService;
import com.songlanyun.modules.account.service.UserIdentityAssetService;
import com.songlanyun.modules.account.service.impl.UserIdentityAssetServiceImpl;
import com.songlanyun.modules.chain.dao.ChainDao;
import com.songlanyun.modules.chain.entity.ChainEntity;
import com.songlanyun.modules.chain.model.dto.*;
import com.songlanyun.modules.chain.model.vo.ChainVO;
import com.songlanyun.modules.chain.service.ChainService;
import com.songlanyun.modules.exception.ConfigException;
import com.songlanyun.modules.integralrecord.entity.IntegralRecord;
import com.songlanyun.modules.integralrecord.service.IntegralRecordService;
import com.songlanyun.modules.memberbill.entity.SaleRefillVoucherBillEntity;
import com.songlanyun.modules.memberbill.service.SaleRefillVoucherBillService;
import com.songlanyun.modules.pointconfig.entity.PointConfig;
import com.songlanyun.modules.pointconfig.service.PointConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.net.URI;
import java.text.MessageFormat;
import java.time.Duration;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 调用区块链服务 api
 *
 * @author zhangqh
 */
@Service
@Slf4j
public class ChainServiceImpl extends ServiceImpl<ChainDao, ChainEntity> implements ChainService {

    RestTemplate restTemplate;

    @Resource
    ChainProperties chainProperties;

    @Resource
    AccountService accountService;

    @Resource
    IntegralRecordService integralRecordService;

    @Resource
    UserIdentityAssetService userIdentityAssetService;

    @Resource
    PointConfigService pointConfigService;

    @Autowired
    private SaleRefillVoucherBillService saleRefillVoucherBillService;

    @Autowired
    private HandlingFeesDao handlingFeesDao;


    @Resource
    RedisUtils redisUtils;
    @PostConstruct
    public void init(){
        restTemplate = new RestTemplateBuilder()
                .setConnectTimeout(Duration.ofSeconds(3))
                .setReadTimeout(Duration.ofSeconds(5))
                .build();
    }

    /**
     * 为账号创建区块链地址 调用区块链服务
     *
     * @return String 用户区块链地址
     */
    @Override
    public String createAccountAddress(Long uid) {
        URI uri = UriComponentsBuilder.fromUriString(chainProperties.getBaseUrl() + chainProperties.getCreateAccountAddressPath()).queryParam("uid", uid).build().toUri();
        log.debug("调用 {} uid={}", uri, uid);
        HttpHeaders httpHeaders = new HttpHeaders();
        Map<String, String> headers = chainProperties.getHeaders();
        headers.forEach(httpHeaders::add);
        ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.GET, new HttpEntity<>(null, httpHeaders), String.class);
        log.debug("调用 出参 {} ", response.getBody());
        return response.getBody();
    }

    /**
     * 用户账户积分提现 调用区块链服务
     *
     * @param chainWithdrawalDTO 积分提现入参
     */
    @Override
    public void createWithdrawal(ChainWithdrawalDTO chainWithdrawalDTO) {
        URI uri = UriComponentsBuilder.fromUriString(chainProperties.getBaseUrl() + chainProperties.getCreateWithdrawalPath()).build().toUri();
        log.debug("调用 {} createWithdrawalDTO ={}", uri, chainWithdrawalDTO);
        HttpHeaders httpHeaders = new HttpHeaders();
        Map<String, String> headers = chainProperties.getHeaders();
        headers.forEach(httpHeaders::add);
        ResponseEntity<String> response = restTemplate.postForEntity(uri, new HttpEntity<>(chainWithdrawalDTO, httpHeaders), String.class);
        log.debug("调用 出参 {} ", response.getBody());
    }

    /**
     * 代币充值成功
     *
     * @param chainNoticeRechargeDTO 代币充值成功回调入参
     */
    @Override
    @Transactional
    public void recharge(ChainNoticeRechargeDTO chainNoticeRechargeDTO) {
        // 1. 判断账户是否存在
        AccountEntity accountEntity = accountService.getUserById(chainNoticeRechargeDTO.getUid(), false);
        if (null == accountEntity) {
            throw new RRException(ConfigException.RECHARGE_ACCOUNT_IS_NOT_EXSIT);
        }
        // 2. 判断订单是否已处理
        LambdaQueryWrapper<ChainEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChainEntity::getBsId, chainNoticeRechargeDTO.getBsId());
        ChainEntity chainEntity = baseMapper.selectOne(queryWrapper);
        if (null != chainEntity) {
            throw new RRException(ConfigException.RECHARGE_HAVE_DONE);
        }
        // 3. 保存充值记录
        chainEntity = new ChainEntity();
        chainEntity.setBsId(chainNoticeRechargeDTO.getBsId());
        chainEntity.setBsType(ChainBsType.CHAIN_IN);
        chainEntity.setBsStatus(ChainBsStatus.SAVE);
        chainEntity.setUid(chainNoticeRechargeDTO.getUid());
        chainEntity.setAmount(chainNoticeRechargeDTO.getAmount());
        chainEntity.setRealAmount(BigDecimal.ZERO);
        chainEntity.setHandlingFee(BigDecimal.ZERO);
        baseMapper.insert(chainEntity);
        // 4. 更新账户积分 如果更新不成功等待定时任务处理
        IntegralRecord integralRecord = new IntegralRecord();
        integralRecord.setUserId(chainEntity.getUid());
        integralRecord.setValue(chainEntity.getAmount());
        integralRecord.setBillType(BillMode.INCOME);
        integralRecord.setOuterMode(OuterMode.EMPTY);
        integralRecord.setInnerMode(InnerMode.RECHARGE_INCOME);
        integralRecord.setModelType(IntegralModelType.RECHARGE_INCOME);
        integralRecord.setModelId(chainEntity.getId());
        integralRecord.setRemark("积分转入");
        integralRecordService.inner(integralRecord);

        chainEntity.setDealTime(new Date());
        chainEntity.setBsStatus(ChainBsStatus.POINT_DEAL);
        this.baseMapper.updateById(chainEntity);
    }

    /**
     * 积分提现成功回调
     *
     * @param noticeRechargeDTO 积分提现成功回调入参
     */
    @Override
    @Transactional
    public void withdrawalNotice(ChainNoticeWithdrawalDTO noticeRechargeDTO) {
        if (!(ChainBsStatus.WITHDRAW_FAIL.equals(noticeRechargeDTO.getBsStatus()) ||
                ChainBsStatus.WITHDRAW_SUCCESS.equals(noticeRechargeDTO.getBsStatus()))) {
            throw new RRException("入参提现状态不对！");
        }
        // 1. 校验提现订单是否存在
        LambdaQueryWrapper<ChainEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChainEntity::getBsId, noticeRechargeDTO.getBsId());
        ChainEntity chainEntity = baseMapper.selectOne(queryWrapper);
        if (null == chainEntity) {
            throw new RRException(ConfigException.WITHDRAWAL_BSID_IS_NOT_EXSIT);
        }
        if (!ChainBsType.CHAIN_OUT.equals(chainEntity.getBsType())) {
            throw new RRException(MessageFormat.format("业务流水号{0}类型为{1}，不能执行提现操作！", chainEntity.getBsId(), chainEntity.getBsType().getMsg()));
        }
        // 2. 校验回调提现用户与订单用户是否一致
        if (!chainEntity.getUid().equals(noticeRechargeDTO.getUid())) {
            throw new RRException(ConfigException.WITHDRAWAL_UID_IS_NOT_SAME);
        }
        // 3. 校验回调的积分数与本地提现积分数是否一致
        if (chainEntity.getRealAmount().compareTo(noticeRechargeDTO.getAmount()) != 0) {
            throw new RRException(ConfigException.WITHDRAWAL_AMOUNT_IS_NOT_SAME);
        }
        if (!ChainBsStatus.WITHDRAWALING.equals(chainEntity.getBsStatus())) {
            throw new RRException(MessageFormat.format("业务流水号{0}状态为{1}，不能执行提现操作！", chainEntity.getBsId(), chainEntity.getBsStatus().getMsg()));
        }

        // 4. 更新本地订单状态
        chainEntity.setBsStatus(noticeRechargeDTO.getBsStatus());
        chainEntity.setWithdrawalTime(new Date());
        baseMapper.updateById(chainEntity);

        // 5. 如果提现失败返还积分 返还 总积分
        if (ChainBsStatus.WITHDRAW_FAIL.equals(noticeRechargeDTO.getBsStatus())) {
            IntegralRecord integralRecord = new IntegralRecord();
            integralRecord.setUserId(chainEntity.getUid());
            integralRecord.setValue(chainEntity.getAmount());
            integralRecord.setBillType(BillMode.INCOME);
            integralRecord.setOuterMode(OuterMode.EMPTY);
            integralRecord.setInnerMode(InnerMode.WITHDRAW_FAIL_INCOME);
            integralRecord.setModelType(IntegralModelType.WITHDRAW_FAIL_INCOME);
            integralRecord.setModelId(chainEntity.getId());
            integralRecord.setRemark("积分转出失败返还");
            integralRecordService.inner(integralRecord);
            chainEntity.setDealTime(new Date());
        } else {
            chainEntity.setDealTime(new Date());
            chainEntity.setBsStatus(ChainBsStatus.POINT_DEAL);
        }
        this.baseMapper.updateById(chainEntity);
    }

    /**
     * 前端获取用户 区块链账户地址
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public AccountEntity getAccountAddress(Long userId) {
        AccountEntity accountEntity = accountService.getUserById(userId, true);
        if (StringUtils.isBlank(accountEntity.getAccountAddress())) {
            String accountAddress = this.createAccountAddress(userId);
            accountEntity.setAccountAddress(accountAddress);
            accountService.updateAccountAddress(userId, accountAddress);
        }
        return accountEntity;
    }

    /**
     * 前端获取用户 区块链账户地址
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public UserIdentityAssetEntity getUserIdentityAsset(Long userId) {
        return userIdentityAssetService.getById(userId, true);
    }


    /**
     * 前端用户提现手续费
     *
     * @param value
     * @return
     */
    @Override
    public UserWithdrawPreviewDTO preview(BigDecimal value) {
        if (null == value || BigDecimal.ZERO.compareTo(value) == 0) {
            return new UserWithdrawPreviewDTO(value, BigDecimal.ZERO,BigDecimal.ZERO,BigDecimal.ZERO);
        }
        PointConfig pointConfig = pointConfigService.loadConfig(true);
        BigDecimal withdrawHandlingFeeRatio = pointConfig.getWithdrawHandlingFeeRatio();
        BigDecimal withdrawHandlingFeeCnhd = pointConfig.getWithdrawHandlingFeeCnhd();
        if (withdrawHandlingFeeRatio.compareTo(BigDecimal.ZERO) == 0) {
            return new UserWithdrawPreviewDTO(value, BigDecimal.ZERO,BigDecimal.ZERO,BigDecimal.ZERO);
        }
        BigDecimal handlingFee = MathUtils.setScaleDown(value.doubleValue() * withdrawHandlingFeeRatio.doubleValue() / 100, 8);
        BigDecimal handlingFeeCnhd = MathUtils.setScaleDown(value.doubleValue() * withdrawHandlingFeeCnhd.doubleValue() / 100, 8);
        BigDecimal facePoint = MathUtils.setScaleDown(value.doubleValue() - handlingFee.doubleValue(), 8);
        BigDecimal facePointCnhd = MathUtils.setScaleDown(value.doubleValue() - handlingFeeCnhd.doubleValue(), 8);
        return new UserWithdrawPreviewDTO(facePoint, handlingFee,handlingFeeCnhd,facePointCnhd);
    }

    /**
     * 前端用户积分提现操作
     * 直接减去对应积分
     *
     * @param userWithdrawalDTO 入参
     * @param userId            用户id
     */
    @Override
    @Transactional
    public void withdrawal(UserWithdrawalDTO userWithdrawalDTO, Long userId) {
        // 获取用户资产信息
        UserIdentityAssetEntity userIdentityAssetEntity = userIdentityAssetService.loadByIdForLock(userId, true);
        String pass = new Sha256Hash(userWithdrawalDTO.getPayPassword(), UserIdentityAssetServiceImpl.PASS_SALT).toHex();

        if (ObjectUtil.isEmpty(userIdentityAssetEntity.getPayPass())) {
            throw new RRException("支付密码没设置", 99999);
        }

        if (!userIdentityAssetEntity.getPayPass().equals(pass)) {
            throw new RRException("支付密码错误");
        }

        // 提现总数量
        BigDecimal amount = userWithdrawalDTO.getAmount();
        // 账户余额
        BigDecimal integralAble = userIdentityAssetEntity.getIntegralAble();
        if (amount.compareTo(integralAble) > 0) {
            throw new RRException(ConfigException.POINT_NOT_FULL);
        }


        // 手续费、实际金额
        UserWithdrawPreviewDTO previewDTO = this.preview(amount);
        // 保存提现数据等待审核
        ChainEntity chainEntity = new ChainEntity();
        chainEntity.setBsId(buidOrder());
        chainEntity.setBsType(ChainConstant.ChainBsType.CHAIN_OUT);
        chainEntity.setBsStatus(ChainConstant.ChainBsStatus.SAVE);
        chainEntity.setUid(userId);
        chainEntity.setTransferNet(userWithdrawalDTO.getTransferNet());
        chainEntity.setPayType(userWithdrawalDTO.getPayType());
        chainEntity.setToAddress(userWithdrawalDTO.getToAddress());
        chainEntity.setAmount(userWithdrawalDTO.getAmount());
        chainEntity.setRealAmount(previewDTO.getRealAmount());
        chainEntity.setHandlingFee(previewDTO.getHandFee());
        baseMapper.insert(chainEntity);
        // 减去相应金额
        outer(chainEntity);



//        PointConfig config = pointConfigService.loadConfig(true);
//        //当前积分价格
//        BigDecimal pointPrice = config.getPointPrice();
//        //转账用户
//        UserIdentityAssetEntity userIdentityAsset = userIdentityAssetService.getById(userId,true);
//        //当前的兑换券余额
//        BigDecimal voucher = userIdentityAsset.getVoucher();
//        if (voucher == null){
//            voucher = BigDecimal.ZERO;
//        }
//        //根据当时市场价换算后的兑换券数量
//        BigDecimal bigDecimal = previewDTO.getHandFee().multiply(pointPrice).setScale(2, BigDecimal.ROUND_HALF_UP);
//        //加完后的兑换券余额
//        BigDecimal addVoucher = voucher.add(bigDecimal);
//        userIdentityAsset.setVoucher(addVoucher);
//
//        userIdentityAssetService.updateById(userIdentityAsset);



    }

    /**
     * 积分提现 减积分
     *
     * @param chainEntity
     */
    @Override
    public void outer(ChainEntity chainEntity) {
        IntegralRecord integralRecord = new IntegralRecord();
        integralRecord.setUserId(chainEntity.getUid());
        integralRecord.setValue(chainEntity.getAmount());
        integralRecord.setBillType(BillMode.EXPENDITURE);
        integralRecord.setOuterMode(OuterMode.WITHDRAWAL_POINT);
        integralRecord.setInnerMode(InnerMode.EMPTY);
        integralRecord.setModelType(IntegralModelType.WITHDRAW_OUT);
        integralRecord.setModelId(chainEntity.getId());
        integralRecord.setRemark("积分转出减少");

        integralRecordService.outer(integralRecord);
    }

    /**
     * 订单号生成方式 时间yyyyMMddHHmmss + uuid
     *
     * @return
     */
    private String buidOrder() {
        return DateUtils.format(new Date(), "yyyyMMddHHmmss") + UUIDUtil.getUUID();
    }

    /**
     * 控制台-查询积分转账记录
     *
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<ChainVO> ipage = this.baseMapper.page(new Query<ChainVO>().getPage(params), params);
        ipage.getRecords().forEach(item -> {
            ChainBsStatus bsStatus = Arrays.stream(ChainBsStatus.values()).filter(chainBsStatus -> chainBsStatus.getCode().equals(item.getBsStatus())).findAny().orElse(null);
            item.setBsStatusName(null == bsStatus ? null : bsStatus.getMsg());
            ChainTransferNet transferNet = Arrays.stream(ChainTransferNet.values()).filter(chainTransferNet -> chainTransferNet.getCode().equals(item.getTransferNet())).findAny().orElse(null);
            item.setTransferNetName(null == transferNet ? null : transferNet.getMsg());
            ChainPayType payType = Arrays.stream(ChainPayType.values()).filter(chainPayType -> chainPayType.getCode().equals(item.getPayType())).findAny().orElse(null);
            item.setPayTypeName(null == payType ? null : payType.getMsg());
        });
        return new PageUtils(ipage);
    }

    /**
     * 控制台-积分转账审核
     *
     * @param chainVO
     */
    @Override
    @Transactional
    public void audit(ChainVO chainVO) {
        ChainEntity chainEntity = this.baseMapper.selectById(chainVO.getId());
        if (!ChainBsStatus.SAVE.equals(chainEntity.getBsStatus())) {
            throw new RRException(MessageFormat.format("订单数据状态为{0}, 不需要审核", chainEntity.getBsStatus().getMsg()));
        }
        // 1. 更新本地状态
        ChainBsStatus chainBsStatus = Arrays.stream(ChainBsStatus.values()).filter(item -> item
                .getCode().equals(chainVO.getBsStatus())).findAny().orElse(null);
        chainEntity.setBsStatus(chainBsStatus);
        chainEntity.setAuditTime(new Date());
        this.baseMapper.updateById(chainEntity);

        // 如果审核不通过，返还 提现操作时减掉的用户积分 返还总积分
        if (ChainBsStatus.AUDIT_FAIL.equals(chainEntity.getBsStatus())) {
            IntegralRecord integralRecord = new IntegralRecord();
            integralRecord.setUserId(chainEntity.getUid());
            integralRecord.setValue(chainEntity.getAmount());
            integralRecord.setBillType(BillMode.INCOME);
            integralRecord.setOuterMode(OuterMode.EMPTY);
            integralRecord.setInnerMode(InnerMode.WITHDRAW_FAIL_INCOME);
            integralRecord.setModelType(IntegralModelType.WITHDRAW_FAIL_INCOME);
            integralRecord.setModelId(chainEntity.getId());
            integralRecord.setRemark("积分转出审核不通过返还");
            integralRecordService.inner(integralRecord);
        }

        // 调用区块链服务提现 提出是扣除手续费的实际积分
        if (ChainBsStatus.WITHDRAWALING.equals(chainEntity.getBsStatus())) {
            ChainWithdrawalDTO chainWithdrawalDTO = new ChainWithdrawalDTO();
            chainWithdrawalDTO.setUid(chainEntity.getUid());
            chainWithdrawalDTO.setBsId(chainEntity.getBsId());
            chainWithdrawalDTO.setToAddress(chainEntity.getToAddress());
            chainWithdrawalDTO.setAmount(chainEntity.getRealAmount());
            try {
                this.createWithdrawal(chainWithdrawalDTO);

                PointConfig pointConfig = pointConfigService.loadConfig(true);

                UserIdentityAssetEntity userIdentityAssetEntity=userIdentityAssetService.getById(chainEntity.getUid());
                BigDecimal voucher = userIdentityAssetEntity.getVoucher();
                //根据当时价格转为兑换券
                BigDecimal decimal = chainVO.getHandlingFee().multiply(pointConfig.getPointPrice()).setScale(2, BigDecimal.ROUND_HALF_UP);
                BigDecimal addVoucher = voucher.add(decimal);
                userIdentityAssetEntity.setVoucher(addVoucher);
                userIdentityAssetService.updateById(userIdentityAssetEntity);
                SaleRefillVoucherBillEntity bill = new SaleRefillVoucherBillEntity();
                bill.setRemark("积分提现");//账单说明
                bill.setBillType(BillConstant.BillMode.INCOME);//账单类型
                bill.setEntryBeforeBalance(voucher);//入帐前的余额
                bill.setEntryAfterBalance(addVoucher);//入帐后的余额
                bill.setEntryValue(decimal);//入帐的额度
//        bill.setSaleOrderCode(outTradeNo);//消费订单编号
                bill.setInnerMode(BillConstant.InnerMode.POINT_WITHDRAWAL);//支出（0普通消费）
                bill.setCreateTimeMillis(System.currentTimeMillis());//创建帐户的时间戳
                bill.setUserId(chainEntity.getUid());//会员id
                saleRefillVoucherBillService.save(bill);
                //70%回收
                HandlingFeesEntity handlingFeesEntity = new HandlingFeesEntity();
                BigDecimal result = MathUtils.setScaleDown(chainVO.getHandlingFee().doubleValue() * 0.7, 8);
                handlingFeesEntity.setHandlingFee(result);
                handlingFeesEntity.setCreatTime(new Date());
                handlingFeesEntity.setUserId(chainEntity.getUid());
                handlingFeesDao.insert(handlingFeesEntity);

            } catch (Exception e) {
                log.error("调用区块链服务提现失败,入参: {}", chainWithdrawalDTO, e);
                throw new RRException("调用区块链服务提现失败！" + e.getMessage());
            }
        }
    }

    /**
     * 实时获取积分价格， 5s钟一次
     *
     * @return
     */
    @Override
    public BigDecimal pointPrice() {
        BigDecimal price = redisUtils.get(RedisKeys.POINT_PRICE_KEY, BigDecimal.class);
        if (null != price) {
            return price;
        }
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(chainProperties.getPointPriceUrl(), String.class);
        if (responseEntity.getStatusCode().equals(HttpStatus.OK)) {
            String body = responseEntity.getBody();
            Wrapper<List<Wrapper.ChainPointPriceDTO>> wrapper = JSON.parseObject(body, new TypeReference<Wrapper<List<Wrapper.ChainPointPriceDTO>>>() {
            });
            if(ObjectUtil.isNull(wrapper)){
                throw new RRException("获取积分价格失败: 未返回价格数据！");
            }
            if (wrapper.success()) {
                List<Wrapper.ChainPointPriceDTO> list = wrapper.getData();
                if (CollectionUtils.isEmpty(list)) {
                    throw new RRException("获取积分价格失败: 未返回积分价格！");
                } else {
                    price = list.get(0).getClose();
                    redisUtils.set(RedisKeys.POINT_PRICE_KEY, price, 5);
                    return price;
                }
            } else {
                throw new RRException("获取积分价格失败: " + wrapper.getMessage() + "!");
            }
        } else {
            throw new RRException("获取积分价格失败：调用积分价格查询接口异常！");
        }
    }
}
